package utils;

import com.orientechnologies.orient.core.command.script.OCommandScript;
import com.orientechnologies.orient.core.db.ODatabaseSession;
import com.orientechnologies.orient.core.metadata.schema.OClass;
import com.orientechnologies.orient.core.metadata.schema.OType;
import com.orientechnologies.orient.core.record.OVertex;
import com.tinkerpop.blueprints.Vertex;
import com.tinkerpop.blueprints.impls.orient.OrientGraph;
import com.tinkerpop.blueprints.impls.orient.OrientGraphNoTx;
import com.tinkerpop.blueprints.impls.orient.OrientVertexType;

import java.util.HashMap;
import java.util.Map;

public class OrientUtils {



    public static void addLawNode(ODatabaseSession db, Map<String, Object> lawPropMap){
        if (db.getClass("Law") == null) {
            OClass lawClass = db.createVertexClass("Law");
            lawClass.createProperty("name", OType.STRING);
            lawClass.createProperty("content", OType.STRING);
            lawClass.createProperty("belongs_law", OType.STRING);
            lawClass.createProperty("level", OType.INTEGER);
            lawClass.createIndex("law_name_index", OClass.INDEX_TYPE.NOTUNIQUE_HASH_INDEX, "name");
        }
        if (db.getClass("BELONGS") == null) {
            db.createEdgeClass("BELONGS");
        }
        OVertex result = db.newVertex("Law");
        String fromName = lawPropMap.get("name").toString();
        String toName = "";
        String matchName = "";
        if(lawPropMap.get("belongs_law") != null)
            toName = lawPropMap.get("belongs_law").toString();
        if(lawPropMap.get("matchStr") != null)
            matchName = lawPropMap.get("matchStr").toString();
        result.setProperty("name", fromName);
        result.setProperty("content", lawPropMap.get("content"));
        result.setProperty("belongs_law", toName);
        result.setProperty("level", lawPropMap.get("level"));
        result.save();
        if (!matchName.equals("")){
            String sql = " CREATE EDGE `BELONGS` " +
                    " FROM (SELECT FROM Law where name = :fromName) " +
                    " TO  (SELECT FROM Law where name matches :matchName)  ";
            Map<String, Object> params = new HashMap<>();
            params.put("fromName", fromName);
            params.put("matchName", matchName);
            db.command(sql, params);
        } else if ( matchName.equals("") && !toName.equals("")){
            String sql = " CREATE EDGE `BELONGS` " +
                    " FROM (SELECT FROM Law where name = :fromName) " +
                    " TO  (SELECT FROM Law where name = :toName) ";
            Map<String, Object> params = new HashMap<>();
            params.put("fromName", fromName);
            params.put("toName", toName);
            db.command(sql, params);
        }

    }

    public static void addCaseNode(ODatabaseSession db, Map<String, Object> casePropMap){

        if (db.getClass("Case") == null) {
            OClass lawClass = db.createVertexClass("Case");
            lawClass.createProperty("case_id", OType.STRING);
            lawClass.createProperty("case_name", OType.STRING);
            lawClass.createProperty("pre_id", OType.STRING);
            lawClass.createProperty("case_type", OType.STRING);
            lawClass.createProperty("case_hierarchy", OType.STRING);
            lawClass.createIndex("case_name_index", OClass.INDEX_TYPE.NOTUNIQUE_HASH_INDEX, "case_name");
        }
        if (db.getClass("BELONGS") == null) {
            db.createEdgeClass("BELONGS");
        }

        String query = "BEGIN;"
        + "LET $case1 = CREATE VERTEX case SET case_id = :case_id;"
        + "LET $case2 = CREATE VERTEX case SET case_id = :pre_id;"
        + "LET $edge = CREATE EDGE belongs FROM $case1 TO $case2;"
        + "LET $prop = UPDATE case " + " set case_name = :case_name, pre_id = :pre_id, case_type = :case_type, " +
                "case_hierarchy = :case_hierarchy where case_id = :case_id;"
        + "COMMIT; RETURN $edge;";
        db.execute("sql", query,  casePropMap);
        //db.command(new OCommandScript("sql", query.toString()).execute(casePropMap));


    }

    public static void addGraphLawNode(OrientGraphNoTx graph, Map<String, Object> lawPropMap){

        if (graph.getVertexType("Law") == null) {
            OrientVertexType lawClass = graph.createVertexType("Law");
            lawClass.createProperty("name", OType.STRING);
            lawClass.createProperty("content", OType.STRING);
            lawClass.createProperty("belongs_law", OType.STRING);
            lawClass.createProperty("level", OType.INTEGER);
            lawClass.createIndex("law_name_index", OClass.INDEX_TYPE.NOTUNIQUE_HASH_INDEX, "name");
        }
        if (graph.getEdgeType("Belongs") == null) {
            graph.createEdgeType("Belongs");
        }

        Vertex vertex = graph.addVertex("class:Law");
        String fromName = lawPropMap.get("name").toString();
        String toName = "";
        String matchName = "";
        if(lawPropMap.get("belongs_law") != null)
            toName = lawPropMap.get("belongs_law").toString();
        if(lawPropMap.get("matchStr") != null)
            matchName = lawPropMap.get("matchStr").toString();
        vertex.setProperty("name", fromName);
        vertex.setProperty("content", lawPropMap.get("content"));
        vertex.setProperty("belongs_law", toName);
        vertex.setProperty("level", lawPropMap.get("level"));
        if (!matchName.equals("")){
            Map<String, Object> params = new HashMap<>();
            params.put("matchName", matchName);
            Iterable<Vertex> vertices = graph.command(new OCommandScript(" MATCH " +
                    "{ class:Law, as:law, where: (name matches :matchName)} " +
                    " RETURN $elements " )).execute(params);
            Vertex matchVertex = vertices.iterator().next();
            vertex.addEdge("belongs", matchVertex);
        } else if ( matchName.equals("") && !toName.equals("")){
            Vertex toVertex = graph.getVertices("Law.name", toName).iterator().next();
            vertex.addEdge("belongs", toVertex);
        }

    }
}
